#pragma once
#include <queue>
#include <vector>
#include <semaphore.h>
#include "Mutex.hpp"
#include "Thread.hpp"
#include "Cond.hpp"



namespace RingBufferModule
{
    using namespace ThreadMoudle;

    template<typename T>
    class RingBuffer
    {

    public:
        RingBuffer(int cap)
        :_cap(cap),_p_step(0),_c_step(0),_buffer(cap)
        {
            sem_init(&_data_sem,0,0);
            sem_init(&_space_sem,0,cap);
        }
        void Pop(T& out)
        {
            sem_wait(&_data_sem);
            {
                LockGuard lockguard(_c_mutex);
                out = _buffer[_c_step++];
                _c_step %= _cap;
            }
            sem_post(&_space_sem);
        }
        void Enqueue(const T& in)
        {
            sem_wait(&_space_sem);
            {
                LockGuard lockguard(_p_mutex);
                _buffer[_p_step++] = in;
                _p_step %= _cap;
            }
            sem_post(&_data_sem);
        }


        ~RingBuffer()
        {
            sem_destroy(&_data_sem);
            sem_destroy(&_space_sem);
        }

    private:
        std::vector<T> _buffer;
        int _cap;
        Mutex _p_mutex;
        Mutex _c_mutex;
        // Cond _p_cond;
        // Cond _c_cond;

        int _p_step;          // 生产者位置
        int _c_step;          // 消费位置


        sem_t _data_sem;
        sem_t _space_sem;
        
    };





}

// // v1
// namespace RingBufferModule
// {
//     using namespace ThreadMoudle;
//     class RingBuffer
//     {

//     public:
//         RingBuffer(int cap)
//         :_cap(cap),_p_step(0),_c_step(0),_buffer(cap)
//         {
//             sem_init(&_data_sem,0,0);
//             sem_init(&_space_sem,0,cap);
//         }
//         void Pop(int& out)
//         {
//             sem_wait(&_data_sem);
//             {
//                 LockGuard lockguard(_c_mutex);
//                 out = _buffer[_c_step++];
//                 _c_step %= _cap;
//             }
//             sem_post(&_space_sem);
//         }
//         void Enqueue(const int& in)
//         {
//             sem_wait(&_space_sem);
//             {
//                 LockGuard lockguard(_p_mutex);
//                 _buffer[_p_step++] = in;
//                 _p_step %= _cap;
//             }
//             sem_post(&_data_sem);
//         }


//         ~RingBuffer()
//         {
//             sem_destroy(&_data_sem);
//             sem_destroy(&_space_sem);
//         }

//     private:
//         std::vector<int> _buffer;
//         int _cap;
//         Mutex _p_mutex;
//         Mutex _c_mutex;
//         // Cond _p_cond;
//         // Cond _c_cond;

//         int _p_step;          // 生产者位置
//         int _c_step;          // 消费位置


//         sem_t _data_sem;
//         sem_t _space_sem;
        
//     };





// }